﻿#ifndef CLIENTSOCKET_H
#define CLIENTSOCKET_H

#include <QObject>
#include <QTcpSocket>
#include <QFile>
#include <QJsonObject>
#include <QJsonDocument>
#include <QJsonObject>
#include <QThread>
#include <QTimer>

class ClientSocket : public QObject
{
    Q_OBJECT
public:
    explicit ClientSocket(QObject *parent = 0);
    ~ClientSocket();
    // 获取当前用户的ID
    int GetUserId() const;
    void SetUserId(const int &id);

    void CheckConnected();
    //void ConnectToHost(const QHostAddress &host,const int &port);

    void SendPackage(const char* str, int length);

signals:
    void signalStatus(const quint8 &state);         //服务器状态：掉线 or 连接，还有登陆，注册也由这个发送，会造成逻辑歧义，应该分开
    void sigUserInfo(const QJsonObject&);           //当前登录用户的个人信息
    void sigFriendList(const QJsonObject&);         //更新好友列表
    void sigUpdateUserStatus(int id,int status);    //好友状态（在线、离线）更新
    void sigFindUser(const QJsonObject&);           //查找好友结果
    void sigRequestAddUser(const QJsonObject&);     //请求添加好友
    void sigDelFriend(int userid);                  //删除好友，发送给客户端通知界面更改
    void sigAddUserResult(QString username,int accept);              //添加好友结果
    void sigChatMsg(const QJsonObject&,int senderid);            //文字聊天消息
public:
    // tcpsocket
    QTcpSocket      *m_pTcpSocket;
    QTimer          *m_timer;
private:
    int             m_nId;
    int             m_seq;        //当前数据包序列号
    QByteArray      m_buffer;     //缓存上一次或多次的未处理的数据,重新粘包
    QByteArray      m_writeBuffer;
    bool            m_bIsStopped;
    bool            m_isOkConnect;
private:
    void initConnection();
    void retry();
    bool Process(const char* inbuf, size_t length);
    void OnRegisterResult(const char* data,int length);
    void OnLoginResult(const char* data,int length);
    void OnUpdateUserInfo(const char* data,int length);
    void OnUpdateUserStatus(int userid, const char* data, int length);
    void OnGotFriendList(const char* data,int length);
    void OnFindUser(const char* data,int length);
    void OnOperateFriend(const char* data,int length);
    void OnChatMsg(const char* data, int length, int senderid);
    void ParseDataToJson(const char* data, int length, QJsonObject& jsonObj);
public slots:
    //发送消息
    void SltSend(int cmd, const QJsonObject& json);
    void SltSendtoTargetid(int cmd,const QJsonObject& json,int targetid);
    //连接服务器
    void ConnectToHost();
    void CloseConnected();
private slots:

    // 与服务器断开链接
    void SltDisconnected();
    // 链接上服务器
    void SltConnected();
    // tcp消息处理
    void SltReadyRead();
    //心跳协议
    void SltHeartbeat();
};

#endif // CLIENTSOCKET_H
